<template>
  <div class="early-warning-box">
    <el-form ref="form" :model="formData" :disabled="popConfig.disabled" :rules="rules" label-width="120px"
             :validate-on-rule-change="false">
      <template v-for="(item, index) in formList">
        <el-form-item
          v-if="item.prop !== 'threshold'"
          :key="`${item.prop}${index}`"
          :style="item.itemStyle || {}"
          :label="item.name"
          :prop="item.prop"
          :class="item.itemClass"
        >
          <component
            :is="item.componentType || 'el-input'"
            v-if="item.prop"
            v-model="formData[item.prop]"
            :clearable="true"
            :class="item.class"
            v-bind="item.attrConfig || {}"
            @change="handlerSelectData(item)"
          >
            <template v-for="option in item.optionList">
              <el-option
                :key="option.code"
                :label="option.name"
                :value="option.code"
                :disabled="option.disabled"
              />
            </template>
          </component>
        </el-form-item>
        <!--   预警阀值及预警级别设置     -->
        <div v-else class="threshold-div">
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span>{{ item.name }}</span>
              <el-button v-if="!popConfig.disabled" style="float: right; padding: 3px 0" type="text"
                         @click.stop="addThreshold" :disabled="thresholdList.length === 3">添加一行
              </el-button>
            </div>
            <template v-for="(o, idx) in thresholdList">
              <div class="el-form">
                <el-form-item :label="o.name + (idx+1)" class="multiple-form-item">
                  <template #default>
                    <div style="display: flex;">
                      <el-form-item :prop="o.typeProp + idx">
                        <el-select
                          v-model="formData[o.typeProp+idx]"
                          placeholder="请选择判断规则"
                          style="width: 100%"
                          :clearable="true"
                        >
                          <template v-for="option in judgeRuleOptions">
                            <el-option
                              :key="option.value"
                              :label="option.label"
                              :value="option.value"
                            />
                          </template>
                        </el-select>
                      </el-form-item>
                      <el-form-item :prop="o.prop + idx">
                        <el-input v-model="formData[o.prop+idx]" placeholder="请输入预警阀值" style="width: 100%"
                                  type="number" />
                      </el-form-item>

                    </div>
                  </template>
                </el-form-item>
                <el-form-item :label="o.levelName" :prop="o.levelProp + idx">
                  <el-select
                    style="width: 80%;margin-right: 10px;"
                    v-model="formData[o.levelProp+idx]"
                    placeholder="请选择预警级别"
                    :clearable="true"
                    @change="handlerThresholdLevelChange(o,idx)"
                  >
                    <template v-for="option in o.thresholdLevelOptions">
                      <el-option
                        :disabled="option.disabled"
                        :key="option.value"
                        :label="option.label"
                        :value="option.value"
                      />
                    </template>
                  </el-select>
                  <el-button v-if="idx >0 &&  !popConfig.disabled" type="danger" size="mini" icon="el-icon-delete"
                             @click="deleteThreshold(idx)" circle></el-button>
                </el-form-item>

              </div>
            </template>
          </el-card>
        </div>
      </template>
    </el-form>
  </div>
</template>

<script>
import { dictMixin } from '@/mixin/dict'
import roomApi from '@/api/apis/sceneRoom'
import api from '@/api/apis/earlyWarning'

import { parseSceneData, parseToSceneInfo, sceneInfoToParam } from '@/utils/scene-data'

export default {
  name: 'AddEarlyWarning',
  mixins: [dictMixin],
  props: {
    // 请求参数
    requestParams: {
      type: Object,
      default: () => ({})
    },
    // 弹窗数据
    popData: {
      type: Object,
      default: () => ({})
    },
    // 弹窗配置
    popConfig: {
      type: Object,
      default: () => ({})
    },
    // 弹窗取消
    close: {
      type: Boolean,
      default: false
    },
    // 弹窗确认
    confirm: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      isAdd: true,
      thresholdList: [
        {
          name: '预警阀值',
          levelName: '预警级别',
          prop: 'thresholdValue',
          typeProp: 'judgeRule',
          levelProp: 'thresholdLevel'
        }
      ],
      judgeRuleOptions: [],
      thresholdLevelOptions: [],
      formData: {
        warningType: 1,
        judgeRule0: '',
        thresholdValue0: '',
        thresholdLevel0: '',
        userIds: []
      },
      formList: [
        {
          name: '预警名称',
          prop: 'warningName',
          attrConfig: { placeholder: '请输入预警名称' }
        },
        {
          name: '所属项目',
          prop: 'sceneProjectId',
          componentType: 'el-select',
          optionList: [],
          selectPath: 'commonSelected',
          selectParams: {
            code: 'SceneProjectSelected'
          },
          attrConfig: {
            placeholder: '请选择所属项目',
            options: []
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '100%' }
        },
        {
          name: '所属场景',
          prop: 'sceneInfo',
          componentType: 'el-cascader',
          attrConfig: {
            placeholder: '请选择所属场景',
            props: {
              checkStrictly: true
            },
            options: []
          }
        },
        {
          name: '关联设备',
          prop: 'meterDeviceId',
          componentType: 'el-select',
          optionList: [],
          attrConfig: {
            placeholder: '请选择关联设备',
            options: []
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '100%' }
        },
        {
          name: '计量条件',
          prop: 'meterCondition',
          componentType: 'el-select',
          optionList: [],
          attrConfig: {
            placeholder: '请选择计量条件',
            options: []
          },
          dataProp: {
            keyProp: 'ecp-admin.earlyWarning.meterCondition',
            nameProp: 'label',
            codeProp: 'value'
          },
          style: { width: '100%' }
        },
        // {
        //   name: ''
        // },
        {
          name: '预警阈值(能耗单位)及预警级别',
          prop: 'threshold'
        },
        {
          name: '推送规则',
          prop: 'pushType',
          componentType: 'el-select',
          optionList: [],
          attrConfig: {
            placeholder: '请选择推送规则',
            options: []
          },
          dataProp: {
            keyProp: 'ecp-admin.earlyWarning.pushType',
            nameProp: 'label',
            codeProp: 'value'
          },
          style: { width: '100%' }
        },
        {
          name: '预警推送目标',
          prop: 'userIds',
          componentType: 'el-select',
          optionList: [],
          selectPath: 'commonSelected',
          selectParams: {
            code: 'UserSelected'
          },
          attrConfig: {
            placeholder: '请选择预警推送目标',
            multiple: true,
            options: []
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          style: { width: '100%' }
        },
        {
          name: '生效时间范围',
          prop: 'timeRange',
          componentType: 'el-date-picker',
          attrConfig: {
            placeholder: '请输入开始时间',
            type: 'datetimerange',
            format: 'yyyy-MM-dd HH:mm',
            'value-format': 'yyyy-MM-dd HH:mm'
          }
        }
      ]
    }
  },
  computed: {
    rules() {
      const rules = {
        warningName: [{ required: true, message: '请输入预警名称', trigger: 'blur' }],
        sceneProjectId: [{ required: true, message: '请选择项目', trigger: 'change' }],
        sceneInfo: [{ required: false, message: '请选择场景', trigger: 'change' }],
        meterDeviceId: [{ required: true, message: '请选择关联设备', trigger: 'change' }],
        meterCondition: [{ required: true, message: '请选择计量条件', trigger: 'change' }],
        pushType: [{ required: true, message: '请选择推送规则', trigger: 'change' }],
        userIds: [{ required: true, message: '请选择预警推送目标', trigger: 'blur' }],
        timeRange: [{ required: true, message: '请选择生效时间范围', trigger: 'change' }]
      }
      for (let i = 0; i < this.thresholdList.length; i++) {
        const item = this.thresholdList[i]
        rules[item.typeProp + i] = [{ required: true, message: '请选择判断规则', trigger: 'change' }]
        rules[item.prop + i] = [
          { required: true, message: '请输入输入预警阀值', trigger: 'blur' },
          {
            trigger: 'blur', index: i, validator: (role, value, callback) => {
              const val = parseInt(value)
              const thresholdLevelKeys = Object.keys(this.formData).filter(item => item.startsWith('thresholdLevel') && item !== ('thresholdLevel' + role.index))
              const levelValue = this.formData[`thresholdLevel${role.index}`]
              if (levelValue != null && levelValue !== '') {
                if (levelValue === '2') { // 橙色预警(二级)
                  const preLevelKey = thresholdLevelKeys.find(item => this.formData[item] === '1')
                  if (preLevelKey != null) {
                    const preIndex = preLevelKey.replace('thresholdLevel', '')
                    const preThresholdValue = this.formData['thresholdValue' + preIndex]
                    if (preThresholdValue != null && val >= parseInt(preThresholdValue)) {
                      callback('阈值必须小于' + preThresholdValue)
                      return
                    }
                  }
                  const nextLevelKey = thresholdLevelKeys.find(item => this.formData[item] === '3')
                  if (nextLevelKey != null) {
                    const nextIndex = nextLevelKey.replace('thresholdLevel', '')
                    const nextThresholdValue = this.formData['thresholdValue' + nextIndex]
                    if (nextThresholdValue != null && val <= parseInt(nextThresholdValue)) {
                      callback('阈值必须大于' + nextThresholdValue)
                      return
                    }
                  }
                } else if (levelValue === '1') { // 红色预警(一级)
                  let preLevelKey = thresholdLevelKeys.find(item => this.formData[item] === '2')
                  if (preLevelKey != null) {
                    const preIndex = preLevelKey.replace('thresholdLevel', '')
                    const preThresholdValue = this.formData['thresholdValue' + preIndex]
                    if (preThresholdValue != null && val <= parseInt(preThresholdValue)) {
                      callback('阈值必须大于' + preThresholdValue)
                      return
                    }
                  }
                  preLevelKey = thresholdLevelKeys.find(item => this.formData[item] === '3')
                  if (preLevelKey != null) {
                    const preIndex = preLevelKey.replace('thresholdLevel', '')
                    const preThresholdValue = this.formData['thresholdValue' + preIndex]
                    if (preThresholdValue != null && val <= parseInt(preThresholdValue)) {
                      callback('阈值必须大于' + preThresholdValue)
                      return
                    }
                  }
                } else { // 黄色预警(三级)
                  let preLevelKey = thresholdLevelKeys.find(item => this.formData[item] === '2')
                  if (preLevelKey != null) {
                    const preIndex = preLevelKey.replace('thresholdLevel', '')
                    const preThresholdValue = this.formData['thresholdValue' + preIndex]
                    if (preThresholdValue != null && val >= parseInt(preThresholdValue)) {
                      callback('阈值必须小于' + preThresholdValue)
                      return
                    }
                  }
                  preLevelKey = thresholdLevelKeys.find(item => this.formData[item] === '3')
                  if (preLevelKey != null) {
                    const preIndex = preLevelKey.replace('thresholdLevel', '')
                    const preThresholdValue = this.formData['thresholdValue' + preIndex]
                    if (preThresholdValue != null && val >= parseInt(preThresholdValue)) {
                      callback('阈值必须小于' + preThresholdValue)
                      return
                    }
                  }
                }
              }
              callback()
            }
          }
        ]
        rules[item.levelProp + i] = [{ required: true, message: '请选择预警级别', trigger: 'change' }]
      }
      return rules
    }
  },
  watch: {
    popData: {
      handler(data) {
        this.isAdd = !data.id
        this.formList.forEach((e) => {
          this.$set(this.formData, e.prop, data[e.prop])
        })

        if (!this.isAdd) {
          this.$set(this.formData, 'id', data.id)
          const sceneInfo = parseToSceneInfo(data)
          this.formData.sceneInfo = sceneInfo
          if (data.sceneProjectId) {
            // 查询场景选择的数据
            this.getRoomList(data.sceneProjectId)
            // 查询设备的数据
            this.getDeviceList(sceneInfo)
          }
          if (data.startTime && data.endTime) {
            this.formData.timeRange = [data.startTime, data.endTime]
          }
          this.getDetail(data.id)
        }
      },
      deep: true,
      immediate: true
    },
    confirm() {
      const sceneInfo = sceneInfoToParam(this.formData.sceneInfo)
      const params = {
        ...(this.formData || {}),
        ...sceneInfo
      }
      const { timeRange } = this.formData
      if (timeRange && timeRange.length === 2) {
        params.startTime = timeRange[0]
        params.endTime = timeRange[1]
      }
      if (sceneInfo == null || sceneInfo.length === 0) {
        delete params.sceneEdificeId
        delete params.sceneFloorId
        delete params.sceneRoomId
      }
      delete params.sceneInfo
      delete params.timeRange
      const arr = []
      for (let i = 0; i < this.thresholdList.length; i++) {
        const item = this.thresholdList[i]
        const obj = { sort: i + 1 }
        obj[item.prop] = params[item.prop + i]
        delete params[item.prop + i]
        obj[item.levelProp] = params[item.levelProp + i]
        delete params[item.levelProp + i]
        obj[item.typeProp] = params[item.typeProp + i]
        delete params[item.typeProp + i]
        arr.push(obj)
      }
      params.thresholdJson = JSON.stringify(arr)
      this.submit(params)
    }
  },
  created() {
    this.getDictData()
  },
  methods: {
    handlerThresholdLevelChange(item, idx) {
      const thresholdLevelKeys = Object.keys(this.formData).filter(item => item.startsWith('thresholdLevel'))
      const selectValues = []
      thresholdLevelKeys.forEach(item => {
        selectValues.push(this.formData[item])
      })
      if (thresholdLevelKeys?.length > 0) {
        this.thresholdList.forEach((threshold, index) => {
          for (const option of threshold.thresholdLevelOptions) {
            option.disabled = selectValues.includes(option.value)
          }
        })
      }
    },
    /**
     * change事件
     */
    handlerSelectData(config) {
      const Ref = this.$refs[config.prop]
      if (Ref && config.isClosePop) {
        Ref.dropDownVisible = false
      }
      const value = this.formData[config.prop]

      if (config.prop === 'sceneProjectId') {
        // 查询场景选择的数据
        this.getRoomList(value)
        this.getDeviceList(this.formData.sceneInfo, true)
      } else if (config.prop === 'sceneInfo') {
        // 查询设备列表
        this.getDeviceList(value, true)
      } else if (config.prop === 'meterDeviceId') {
        // 计量设备选择
        console.log(config)
        this.setUnit(config, value)
      } else if (config.prop === 'meterCondition') {
        this.disablePushType(value)
      }
    },
    /**
     * 禁用推送规则选项
     */
    disablePushType(value) {
      const item = this.formList[6]
      if (item.optionList.length > 0) {
        item.optionList.forEach(option => {
          option.disabled = option.value >= (value === '3' || value === '2' ? 2 : 999)
        })
        if (this.formData.pushType) {
          this.formData.pushType = ''
        }
        this.$set(this.formList, 6, { ...item })
      }
    },
    /**
     * 提交
     */
    submit(params) {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          const res = await this.$api.earlyWarning[this.isAdd ? 'add' : 'update'](params)
          if (Number(res.code) === 1000) {
            this.$message.success(`${this.isAdd ? '新增' : '编辑'}成功！`)
            this.$emit('onFinish', 'early-warning-add')
          }
        }
      })
    },
    /**
     * 增加一行预警阀值设置
     */
    addThreshold(index) {
      if (this.thresholdList.length < 3) {
        this.thresholdList.push({
          name: '预警阀值',
          prop: 'thresholdValue',
          typeProp: 'judgeRule',
          levelName: '预警级别',
          levelProp: 'thresholdLevel',
          thresholdLevelOptions: this.thresholdLevelOptions.map(item => {
            const res = Object.assign({}, item)
            res.disabled = this.formData.thresholdLevel0 === item.value || this.formData.thresholdLevel1 === item.value || this.formData.thresholdLevel2 === item.value
            return res
          })

        })
      }
      // console.log(this.$refs.form)
      // setTimeout(()=>this.$refs.form.clearValidate(), 100)
    },
    /**
     * 删除一行预警阀值设置
     *
     */
    deleteThreshold(idx) {
      this.thresholdList.splice(idx, 1)
    },
    /**
     * 设置对应单位
     */
    setUnit(config, value) {
      const item = config.optionList.find(item => item.value === value)
      const energyTypeUnit = item.baseObj.energyTypeUnit || ''
      const selectItem = this.formList[5]
      selectItem.name = `预警推送目标预警阀值(${energyTypeUnit})及预警级别`
      this.$set(this.formList, 5, { ...selectItem })
    },
    /**
     * 获取空间列表
     * @param sceneProjectId
     */
    async getRoomList(sceneProjectId) {
      const res = await roomApi.queryRoomList({
        sceneProjectId,
        sortColumn: 'floorName',
        sortOrder: 'asc'
      })
      const roomList = parseSceneData(res.data)
      const item = this.formList[2]
      item.attrConfig.options = roomList
      this.$set(this.formList, 2, { ...item })
    },
    /**
     * 获取设备列表
     */
    async getDeviceList(sceneInfo, reset = false) {
      const params = sceneInfoToParam(sceneInfo)
      params.sceneProjectId = this.formData.sceneProjectId
      const res = await this.$api.commonSelected({
        code: 'MeterDeviceSelected',
        param: JSON.stringify(params)
      })
      const item = this.formList[3]
      item.optionList = res.data.map(device => {
        device.name = device.label
        device.code = device.value
        return device
      })
      if (reset) {
        this.formData.meterDeviceId = ''
      }
      this.$set(this.formList, 3, { ...item })
    },
    /**
     * 获取关联的用户
     */
    async getDetail(id) {
      const res = await api.detail({ id })
      const { warningUsers, warningThresholds } = res.data
      this.formData.userIds = warningUsers.map(item => item.userId)
      this.thresholdList = []
      for (let i = 0; i < warningThresholds.length; i++) {
        const item = warningThresholds[i]
        this.addThreshold(i)
        this.$set(this.formData, this.thresholdList[i].typeProp + i, item.judgeRule)
        this.$set(this.formData, this.thresholdList[i].prop + i, item.thresholdValue)
        this.$set(this.formData, this.thresholdList[i].levelProp + i, item.thresholdLevel)
      }
    },
    /**
     * 获取字段数据
     */
    async getDictData() {
      const judgeRuleDict = 'ecp-admin.earlyWarningThreshold.judgeRule'
      const thresholdLevelDict = 'ecp-admin.earlyWarningThreshold.thresholdLevel'
      const res = await this.$api.dictList({
        codeList: [
          judgeRuleDict,
          thresholdLevelDict,
          'ecp-admin.earlyWarning.meterCondition',
          'ecp-admin.earlyWarning.pushType'
        ]
      })
      this.judgeRuleOptions = res.data[judgeRuleDict]
      this.thresholdLevelOptions = res.data[thresholdLevelDict]
      this.thresholdList[0].thresholdLevelOptions = res.data[thresholdLevelDict]
      for (let i = 0; i < this.formList.length; i++) {
        const item = this.formList[i]
        const { keyProp } = item.dataProp || {}
        if (keyProp) {
          item.optionList = res.data[keyProp].map(dict => {
            dict.name = dict.label
            dict.code = dict.value
            return dict
          })
          this.$set(this.formList, i, { ...item })
        }
      }
      if (this.formData.meterDeviceId) {
        this.setUnit(this.formList[3], this.formData.meterDeviceId)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.early-warning-box {
  color: #333;
  padding: 0 20px;

  ::v-deep .el-form {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;

    .threshold-div {
      width: 100%;
      margin: 0 0 20px 0;
    }

    .el-form-item {
      width: calc(50% - 10px);

      &.width100p {
        width: 100%;
      }

      .el-form-item__label {
        color: #666;
        font-size: 14px;
      }

      &.form-sub-title {
        width: 100%;

        .el-form-item__label {
          display: flex;
          align-items: center;
          justify-content: flex-start;
          font-weight: bold;
          color: #333;
          font-size: 16px;
          line-height: 1;

          &::before {
            content: '';
            display: inline-block;
            width: 4px;
            height: 15px;
            background-color: #00858d;
            margin-right: 5px;
          }
        }
      }
    }

    .el-select,
    .el-cascader {
      width: 100%;
    }
  }
}
</style>
